package cn.i7baozh.starter.client.handler;

import cn.i7baozh.starter.common.response.WebResponseResult;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.FileCopyUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;

/**
 * sentinel 超出限流错误信息封装
 * https://blog.csdn.net/Saintmm/article/details/118656380
 * @author : baoqi.zhang
 * @date :   2022/5/21 0:29
 */
@Slf4j
public class SentinelBlockedHandler implements BlockExceptionHandler {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void handle(HttpServletRequest httpServletRequest,
                       HttpServletResponse httpServletResponse, BlockException e) throws Exception {
        WebResponseResult webResponseResult = new WebResponseResult();
        webResponseResult.setCode(HttpStatus.SC_TOO_MANY_REQUESTS);
        webResponseResult.setMessage("the path [" + httpServletRequest.getRequestURI() + "] overflow !");
        String text = getOutputText(webResponseResult);
        byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
        httpServletResponse.setContentType(ContentType.APPLICATION_JSON.toString());
        FileCopyUtils.copy(bytes, httpServletResponse.getOutputStream());
    }

    /**
     * 获取内容
     *
     * @param webResponseResult
     * @return
     */
    protected String getOutputText(WebResponseResult webResponseResult) {
        try {
            return objectMapper.writeValueAsString(webResponseResult);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
}
